using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DocumentCreationSystem.Models;

namespace DocumentCreationSystem
{
    /// <summary>
    /// .txt到.md转换功能测试
    /// </summary>
    public class TestTxtToMdConversion
    {
        public static async Task Main(string[] args)
        {
            Console.WriteLine("=== .txt到.md转换功能测试 ===\n");

            try
            {
                // 创建测试项目
                await CreateTestProject();

                // 测试转换逻辑
                await TestConversionLogic();

                Console.WriteLine("\n=== 测试完成 ===");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"测试失败: {ex.Message}");
                Console.WriteLine($"详细错误: {ex}");
            }
        }

        private static async Task CreateTestProject()
        {
            Console.WriteLine("1. 创建测试项目");

            var testProjectPath = Path.Combine(Environment.CurrentDirectory, "TestProject");
            
            // 清理现有测试项目
            if (Directory.Exists(testProjectPath))
            {
                Directory.Delete(testProjectPath, true);
            }

            // 创建测试项目结构
            Directory.CreateDirectory(testProjectPath);
            Directory.CreateDirectory(Path.Combine(testProjectPath, "章节"));
            Directory.CreateDirectory(Path.Combine(testProjectPath, "设定"));

            // 创建测试文件
            await File.WriteAllTextAsync(
                Path.Combine(testProjectPath, "第一章.txt"),
                "# 第一章 开始\n\n这是第一章的内容。\n\n主角登场了。");

            await File.WriteAllTextAsync(
                Path.Combine(testProjectPath, "第二章.txt"),
                "# 第二章 冒险\n\n这是第二章的内容。\n\n开始了新的冒险。");

            await File.WriteAllTextAsync(
                Path.Combine(testProjectPath, "章节", "第三章.txt"),
                "# 第三章 挑战\n\n这是第三章的内容。\n\n面临重大挑战。");

            await File.WriteAllTextAsync(
                Path.Combine(testProjectPath, "设定", "角色设定.txt"),
                "# 角色设定\n\n## 主角\n- 姓名：张三\n- 年龄：18\n\n## 配角\n- 姓名：李四\n- 年龄：20");

            await File.WriteAllTextAsync(
                Path.Combine(testProjectPath, "设定", "世界观.txt"),
                "# 世界观设定\n\n这是一个奇幻世界。\n\n有魔法和怪物。");

            // 创建非txt文件
            await File.WriteAllTextAsync(
                Path.Combine(testProjectPath, "说明.docx"),
                "这是一个docx文件，应该被直接复制。");

            await File.WriteAllTextAsync(
                Path.Combine(testProjectPath, "配置.json"),
                "{\n  \"version\": \"1.0\",\n  \"author\": \"测试作者\"\n}");

            Console.WriteLine($"测试项目已创建: {testProjectPath}");
            Console.WriteLine("项目结构:");
            PrintDirectoryStructure(testProjectPath, "");
        }

        private static async Task TestConversionLogic()
        {
            Console.WriteLine("\n2. 测试转换逻辑");

            var sourceDir = Path.Combine(Environment.CurrentDirectory, "TestProject");
            var targetDir = sourceDir + ".MD";

            // 清理目标目录
            if (Directory.Exists(targetDir))
            {
                Directory.Delete(targetDir, true);
            }

            // 执行转换
            await CopyAndConvertDirectoryAsync(sourceDir, targetDir);

            Console.WriteLine($"转换完成: {targetDir}");
            Console.WriteLine("转换后的项目结构:");
            PrintDirectoryStructure(targetDir, "");

            // 验证转换结果
            await VerifyConversionResults(sourceDir, targetDir);
        }

        private static async Task CopyAndConvertDirectoryAsync(string sourceDir, string targetDir)
        {
            // 确保目标目录存在
            Directory.CreateDirectory(targetDir);

            // 复制所有文件
            var files = Directory.GetFiles(sourceDir);
            foreach (var file in files)
            {
                var fileName = Path.GetFileName(file);
                var fileExtension = Path.GetExtension(file).ToLower();
                
                string targetFile;
                
                if (fileExtension == ".txt")
                {
                    // 将.txt文件转换为.md文件
                    var nameWithoutExtension = Path.GetFileNameWithoutExtension(file);
                    targetFile = Path.Combine(targetDir, nameWithoutExtension + ".md");
                    
                    Console.WriteLine($"转换文件: {Path.GetFileName(file)} -> {Path.GetFileName(targetFile)}");
                    
                    // 读取原文件内容并写入新文件
                    var content = await File.ReadAllTextAsync(file, System.Text.Encoding.UTF8);
                    await File.WriteAllTextAsync(targetFile, content, System.Text.Encoding.UTF8);
                }
                else
                {
                    // 其他文件直接复制
                    targetFile = Path.Combine(targetDir, fileName);
                    
                    Console.WriteLine($"复制文件: {fileName}");
                    File.Copy(file, targetFile, true);
                }
            }

            // 递归处理子目录
            var directories = Directory.GetDirectories(sourceDir);
            foreach (var directory in directories)
            {
                var dirName = Path.GetFileName(directory);
                var targetSubDir = Path.Combine(targetDir, dirName);
                
                await CopyAndConvertDirectoryAsync(directory, targetSubDir);
            }
        }

        private static async Task VerifyConversionResults(string sourceDir, string targetDir)
        {
            Console.WriteLine("\n3. 验证转换结果");

            var verificationResults = new List<string>();

            // 检查.txt文件是否转换为.md
            var txtFiles = Directory.GetFiles(sourceDir, "*.txt", SearchOption.AllDirectories);
            foreach (var txtFile in txtFiles)
            {
                var relativePath = Path.GetRelativePath(sourceDir, txtFile);
                var expectedMdPath = Path.Combine(targetDir, 
                    Path.ChangeExtension(relativePath, ".md"));

                if (File.Exists(expectedMdPath))
                {
                    var originalContent = await File.ReadAllTextAsync(txtFile);
                    var convertedContent = await File.ReadAllTextAsync(expectedMdPath);
                    
                    if (originalContent == convertedContent)
                    {
                        verificationResults.Add($"✅ {relativePath} -> {Path.GetRelativePath(targetDir, expectedMdPath)} (内容一致)");
                    }
                    else
                    {
                        verificationResults.Add($"❌ {relativePath} -> {Path.GetRelativePath(targetDir, expectedMdPath)} (内容不一致)");
                    }
                }
                else
                {
                    verificationResults.Add($"❌ {relativePath} 未找到对应的.md文件");
                }
            }

            // 检查非.txt文件是否正确复制
            var nonTxtFiles = Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories)
                .Where(f => !f.EndsWith(".txt", StringComparison.OrdinalIgnoreCase));

            foreach (var file in nonTxtFiles)
            {
                var relativePath = Path.GetRelativePath(sourceDir, file);
                var expectedTargetPath = Path.Combine(targetDir, relativePath);

                if (File.Exists(expectedTargetPath))
                {
                    verificationResults.Add($"✅ {relativePath} (正确复制)");
                }
                else
                {
                    verificationResults.Add($"❌ {relativePath} 未找到");
                }
            }

            // 输出验证结果
            Console.WriteLine("验证结果:");
            foreach (var result in verificationResults)
            {
                Console.WriteLine($"  {result}");
            }

            var successCount = verificationResults.Count(r => r.StartsWith("✅"));
            var totalCount = verificationResults.Count;
            Console.WriteLine($"\n验证完成: {successCount}/{totalCount} 项通过");
        }

        private static void PrintDirectoryStructure(string path, string indent)
        {
            try
            {
                var dirName = Path.GetFileName(path);
                if (string.IsNullOrEmpty(dirName))
                    dirName = path;

                Console.WriteLine($"{indent}{dirName}/");

                var files = Directory.GetFiles(path);
                var directories = Directory.GetDirectories(path);

                foreach (var file in files)
                {
                    Console.WriteLine($"{indent}  {Path.GetFileName(file)}");
                }

                foreach (var directory in directories)
                {
                    PrintDirectoryStructure(directory, indent + "  ");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{indent}[错误: {ex.Message}]");
            }
        }
    }
}
